package com.atguigu.gulimall.order.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Exchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author 小坏
 * @Date 2021/2/15 2:22
 * @Version 1.0
 * @program: 父工程 gulimall 万物起源之地
 * <p>
 * MQ快速配置
 */


@Configuration
public class MyRabbitMQConfig {


//    @RabbitListener(queues = "order.release.order.queue")
//    public void Listener(OrderEntity entity, Channel channel, Message message) throws IOException {
//        //因为开启了手动签收、需要从通道里获取、false 是否批量监听、只监听一个
//        channel.basicAck (message.getMessageProperties ().getDeliveryTag (), false);
//        System.out.println ("收到消息" + entity);
//    }

    //@Bean Binding, Queue, Exchange 在spring里面加组件的方式默认放到容器中就生效

    /**
     * @return
     * @Bean的作用 容器中 Binding, Queue, Exchange 都会自动创建（rabbitMQ没用的情况下）
     * RabbitMQ只要有。@Bean声明的属性发生的变化也不会覆盖
     */

    @Bean
    public Queue orderDelayQueue() {
        /**
         * 全参解释：
         * String name(队列名字),
         * boolean durable(持久化),
         * boolean exclusive(是不是排他的),
         * boolean autoDelete(是不是自动删除),
         * Map<String, Object> arguments(有没有自定义属性)
         *
         *
         *  自定义属性：
         *      x-dead-letter-exchange:order-event-exchange
         *      x-dead-letter-routing-key: order.release.order
         *      x-message-ttl: 60000
         *
         */

        Map<String, Object> arguments = new HashMap<> ();
        arguments.put ("x-dead-letter-exchange", "order-event-exchange"); //死信路由
        arguments.put ("x-dead-letter-routing-key", "order.release.order");//死信路由键
        arguments.put ("x-message-ttl", 60000);//消息过期时间

        //设置队列里三个属性给死信用
        Queue queue = new Queue ("order.delay.queue", true, false, false, arguments);
        return queue;
    }

    @Bean
    public Queue orderReleaseOrderQueue() {
        //超过30分钟的来到死信队列里
        Queue queue = new Queue ("order.release.order.queue", true, false, false);
        return queue;
    }

    @Bean
    public Exchange orderEventExchange() {
        /**
         *
         * 创建topic交换机
         * 参数解释
         * String name, boolean durable(持久化), boolean autoDelete(不用自动删除), Map<String, Object> arguments
         */
        return new TopicExchange ("order-event-exchange", true, false);
    }


    @Bean
    public Binding orderCreateOrderBinding() {
        /**
         * 这个时正常的
         * 参数解释：
         *  String destination(目的地), DestinationType destinationTyp(目的地的类型),
         *  String exchange(那个交换机), String routingKey(路由键),
         * 	Map<String, Object> arguments
         */
        return new Binding ("order.delay.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.create.order", null);
    }


    @Bean
    public Binding orderReleaseOrderBinding() {

        /**
         * 这个死信的
         * 参数解释：
         *  String destination(目的地), DestinationType destinationTyp(目的地的类型),
         *  String exchange(那个交换机), String routingKey(路由键),
         * 	Map<String, Object> arguments
         */
        return new Binding ("order.release.order.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.release.order", null);
    }


    /**
     * 订单释放直接和库存进行绑定
     *
     * @return
     */

    @Bean
    public Binding orderReleaseOtherBinding() {
        return new Binding ("stock.release.stock.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.release.other.#", null);
    }

    /**
     * 监听秒杀的队列
     */
    @Bean
    public Queue orderSeckillOrderQueue() {
        /**
         * String name,
         * boolean durable, 是否持久化
         * boolean exclusive, 是否排他的（大家都能监听用、谁抢到、是谁的）
         * boolean autoDelete, 是否自动删除
         * Map<String, Object> arguments  参数信息、这是普通队列（不需要参数）
         */
        return new Queue ("order.seckill.order.queue", true, false, false);
    }


    /**
     * 绑定秒杀和订单的交换机
     */
    @Bean
    public Binding orderSeckillOrderQueueBinding() {
        /**
         * String destination, 目的地
         * DestinationType destinationType, 目的地的类型：是队列
         * String exchange, 交换机
         * String routingKey, 路由键
         * 	Map<String, Object> arguments 参数信息、这是普通队列（不需要参数）
         */
        return new Binding ("order.seckill.order.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.seckill.order",
                null);
    }
}
